package scottb.flex;

import java.awt.*;

public class GroupLayoutManager extends FlexLayoutManager {

    public Dimension preferredLayoutSize(Container container) {

        FlexLayout flex = (FlexLayout) container;
        Dimension childrenPreferredSize = null;

        int width = 0;

        if(flex.width() != null) {
            width = flex.width();
        }
        else {
            childrenPreferredSize = getChildrenPreferredSize(flex);
            width = childrenPreferredSize.width;
        }

        int height = 0;

        if(flex.height() != null) {
            height = flex.height();
        }
        else {

            if(null == childrenPreferredSize) {
                childrenPreferredSize = getChildrenPreferredSize(flex);
            }

            height = childrenPreferredSize.height;
        }

        return new Dimension(width, height);
    }

    private Dimension getChildrenPreferredSize(FlexLayout group) {

        int width = 0;
        int height = 0;

        for(Component c : group.getComponents()) {

            Dimension size = c.getPreferredSize();

            if(size.getWidth() > width) {
                width = (int) size.getWidth();
            }

            if(size.getHeight() > height) {
                height = (int) size.getHeight();
            }
        }

        return new Dimension(width, height);
    }

    public void layoutContainer(Container container) {

        Group group = (Group) container;

       for(Component childComponent : group.getComponents()) {

           if(childComponent instanceof FlexLayout) {
               layoutFlex(group, (FlexLayout) childComponent);
           }
           else {
               childComponent.setLocation(0, 0);
               childComponent.setBounds(0, 0, childComponent.getPreferredSize().width, childComponent.getPreferredSize().height);
               childComponent.setSize(childComponent.getPreferredSize().width, childComponent.getPreferredSize().height);
           }
       }
    }

    private void layoutFlex(Group parent, FlexLayout flex) {

        int x = getX(parent, flex);
        int y = getY(parent, flex);
        int width = getWidth(parent, flex, x);
        int height = getHeight(parent, flex, y);

        flex.setLocation(x, y);
        flex.setBounds(x, y, width, height);
        flex.setSize(width, height);
    }

    private int getX(Group parent, FlexLayout flex) {

        int x = 0;

        if(flex.left() != null) {

            x = flex.left();
        }
        else if(flex.horizontalCenter() != null) {

            x = (parent.getWidth() / 2) - (flex.getPreferredSize().width / 2) + flex.horizontalCenter();
        }
        else if(flex.right()  != null) {

            x = parent.getWidth() - flex.right();

            if(flex.width() != null) {

                x -= flex.width();
            }
            else {

                x -= flex.getPreferredSize().width;
            }
        }

        return x;
    }

    private int getY(Group parent, FlexLayout flex) {

        int y = 0;

        if(flex.top() != null) {

            y = flex.top();
        }
        else if(flex.verticalCenter() != null) {

            y = (parent.getHeight() / 2) - (flex.getPreferredSize().height / 2) + flex.verticalCenter();
        }
        else if(flex.bottom() != null) {

            y = parent.getHeight() - flex.bottom();

            if(flex.height() != null) {

                y -= flex.height();
            }
            else {

                y -= flex.getPreferredSize().height;
            }
        }

        return y;
    }

    private int getWidth(Group parent, FlexLayout flex, int x) {

        int width = 0;

        if(flex.right() != null) {
            width = parent.getWidth() - flex.right() - x;
        }
        else if(flex.width() != null) {
            width = flex.width();
        }
        else {
            Dimension size = flex.getPreferredSize();
            width = (int) size.getWidth();
        }

        return width;
    }

    private int getHeight(Group parent, FlexLayout flex, int y) {

        int height = 0;

        if(flex.bottom() != null) {
            height = parent.getHeight() - flex.bottom() - y;
        }
        else if(flex.height() != null) {
            height = flex.height();
        }
        else {
            Dimension size = flex.getPreferredSize();
            height = (int) size.getHeight();
        }

        return height;
    }
}
